package com.gc.cscott.domain.contest;

import com.gc.cscott.domain.contest.numbers.TaskNumber;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterables;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

/**
 *
 * @author root
 */
public class Contest {
    String name = null;
    String taskDir = null;
    String resultDir = null;
    List<Task> tasksList;
    transient Map<TaskNumber, Task> taskMap = null;
    List<Source> sourcesList;
    List<VerifierLocation> verifierLocationList;
    transient Map<TaskNumber, VerifierLocation> verifierLocationMap;
    String workDir;

    protected void initTransients(){
        if (taskMap==null){
            Builder<TaskNumber, Task> builder = ImmutableMap.<TaskNumber, Task>builder();
            for(Task task:tasksList){
                builder.put(task.getNumber(), task);
            }
            taskMap = builder.build();
        }
        if (verifierLocationMap==null){
            Builder<TaskNumber, VerifierLocation> builder = ImmutableMap.<TaskNumber, VerifierLocation>builder();
            for(VerifierLocation verifierLocation:verifierLocationList){
                builder.put(verifierLocation.getTaskNumber(), verifierLocation);
            }
            verifierLocationMap = builder.build();
        }

    }

    public Task getTask(TaskNumber taskNumber){
        initTransients();
        return Preconditions.checkNotNull(taskMap.get(taskNumber), "No task with number %s",taskNumber);
    }
    public List<Task> getTasks(Collection<TaskNumber> taskNumbers){
        initTransients();
        ImmutableList.Builder<Task> result = ImmutableList.<Task>builder();
        for(TaskNumber taskNumber:taskNumbers){
            result.add(getTask(taskNumber));
        }
        return result.build();
    }

    public List<TaskNumber> getTaskNumbersAvailable(){
        initTransients();
        return ImmutableList.copyOf(new TreeSet<TaskNumber>(taskMap.keySet()));
    }

    public VerifierLocation getVerifierLocation(TaskNumber taskNumber){
        initTransients();
        return verifierLocationMap.get(taskNumber);
    }

    public String getResultDir() {
        return resultDir;
    }

    public void setResultDir(String resultDir) {
        this.resultDir = resultDir;
    }

    public String getTaskDir() {
        return taskDir;
    }

    public String getName() {
        return name;
    }

    public List<Task> getTasksList() {
        return tasksList;
    }


    public List<Source> getSourcesList() {
        return sourcesList;
    }

    public List<Source> getEnabledSourcesList(){
        return ImmutableList.copyOf(Iterables.filter(sourcesList, new Predicate<Source>(){
            public boolean apply(Source input) {
                return input.isEnabled();
            }
        }));
    }

    public List<VerifierLocation> getJudgeList() {
        return verifierLocationList;
    }

    public String getWorkDir() {
        return workDir;
    }

}
